package com.xutils.netty.push;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * Created by ketian on 2014/9/24.
 */
public class PushMsgLongClient {

    private Bootstrap mBootstrap = new Bootstrap();
    private EventLoopGroup mWorkerGroup;
    private ChannelFuture mChannelFuture;

    /**
     * 开始连接推送长连接
     *
     * @throws Exception
     */
    public void run(String ip, int port, final PushCallBack listener) throws Exception {
        mWorkerGroup = new NioEventLoopGroup();

        mBootstrap.group(mWorkerGroup);
        mBootstrap.channel(NioSocketChannel.class);
        mBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
        mBootstrap.option(ChannelOption.SO_KEEPALIVE, true);

        mBootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast("idleStateHandler", new IdleStateHandler(60, 15, 13, TimeUnit.SECONDS));
                pipeline.addLast("HeartbeatHandler", new HeartbeatHandler());

                // 以("\n")为结尾分割的 解码器
                pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                // 字符串解码 和 编码
                pipeline.addLast("decoder", new StringDecoder());
                pipeline.addLast("encoder", new StringEncoder());
                // 推送的逻辑
                pipeline.addLast("handler", new PushChannelHandle(listener));
            }
        });

        // start client
        mChannelFuture = mBootstrap.connect(ip, port).sync();

    }

    /**
     * 停止推送长连接
     */
    public void stop() {
        mWorkerGroup.shutdownGracefully();
    }


}
